﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using Isuka.Reflection;

namespace Isuka.Collections
{
    public static class CollectionExtensions
    {
        /// <summary>
        /// プロパティ名をキーとして、値を設定する。
        /// </summary>
        /// <typeparam name="TValue">プロパティの型</typeparam>
        /// <param name="dictionary">値を追加する辞書</param>
        /// <param name="expr">プロパティ取得式</param>
        /// <exception cref="ArugmentException">キーがすでに存在する場合</exception>
        /// <exception cref="ArugmentNullException">式が null の場合</exception>
        /// <returns></returns>
        public static void Add<TValue>(this IDictionary<string, TValue> dictionary, Expression<Func<TValue>> expr)
        {
            Contract.Requires<ArgumentNullException>(dictionary != null, "dictionary");
            Contract.Requires(expr != null);

            var name = Gate.NotNull(MemberHelper.GetMemberInfo(expr)).Name;
            var func = expr.Compile();
            dictionary.Add(name, func());
        }

        public static int IndexOf<T>(this LinkedList<T> source, LinkedListNode<T> node)
        {
            Contract.Requires<ArgumentNullException>(source != null, "source");

            if (node != null && object.ReferenceEquals(node.List, source))
            {
                var n = source.First;
                for (var i = 0; i < source.Count; i++)
                {
                    if (object.ReferenceEquals(n, node))
                    {
                        return i;
                    }
                }
            }
            return -1;
        }
    }
}
